package controller

import (
	"context"
	"github.com/e421083458/gin_scaffold/dao"
	"github.com/e421083458/gin_scaffold/dto"
	"github.com/e421083458/gin_scaffold/middleware"
	jwt "github.com/e421083458/gin_scaffold/public"
	"github.com/e421083458/golang_common/lib"
	"github.com/gin-gonic/gin"
	"github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
	"github.com/wechatpay-apiv3/wechatpay-go/core/downloader"
	"github.com/wechatpay-apiv3/wechatpay-go/core/notify"
	"github.com/wechatpay-apiv3/wechatpay-go/services/payments"
	"log"
)

type OrderController struct {
}

//  不要求登录的接口 公共接口
func OrderNoLogin(router *gin.RouterGroup) {
	curd := OrderController{}
	router.GET("/sort", curd.Category)            //商品分类
	router.GET("/unscramble", curd.Unscramble)    //标签分类列表
	router.GET("/product", curd.Product)          //商品
	router.GET("/product_info", curd.ProductInfo) //商品详情

	router.POST("/notify_url", curd.NotifyUrl)
}

//  要求登录的接口
func OrderLogin(router *gin.RouterGroup) {
	curd := OrderController{}
	router.POST("/create", curd.Create)              //生成支付订单
	router.POST("/orders", curd.OrderList)           //订单列表
	router.POST("/order_info", curd.OrderInfo)       //订单信息
	router.POST("/order_receive", curd.OrderReceive) //订单收货
}

//获取分类
func (o *OrderController) Category(c *gin.Context) {

	tx, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}

	err, order := (&dao.Sort{}).SelectSort(c, tx)
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	middleware.ResponseSuccess(c, order)
}

//获取产品
func (o *OrderController) OrderList(c *gin.Context) {

	tx, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	token := c.Request.Header.Get("token") //从headers获取token
	claims, err0 := jwt.ParseToken(token)
	if err0 != nil {
		return
	}

	parms := &dto.OrderSearch{}
	if err := parms.BindingValidParams(c); err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	parms.Uid = claims.Uid
	//订单状态筛选
	status := parms.Status
	log.Println(status)
	err, orders := (&dao.Order{}).SelectOrder(c, tx, parms.Uid, status)
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	middleware.ResponseSuccess(c, orders)
}

//订单信息
func (o *OrderController) OrderInfo(c *gin.Context) {
	tx, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	parms := &dto.Orderinfo{}
	if err := parms.BindingValidParams(c); err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}

	err, product := (&dao.Order{}).OrderInfo(c, tx, parms.OrderId)
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	middleware.ResponseSuccess(c, product)
}

//订单收货
func (o *OrderController) OrderReceive(c *gin.Context) {

	tx, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	parms := &dto.Orderinfo{}
	if err := parms.BindingValidParams(c); err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}

	err, upRes := (&dao.Order{}).OrfSave(c, tx, parms.OrderId, 2)
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	middleware.ResponseSuccess(c, upRes)
}

//获取产品
func (o *OrderController) Product(c *gin.Context) {

	tx, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	parms := &dto.UType{}
	if err := parms.BindingValidParams(c); err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	err, product := (&dao.Product{}).SelectProduct(c, tx, parms.UnsId)
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	middleware.ResponseSuccess(c, product)
}

//获取产品
func (o *OrderController) Unscramble(c *gin.Context) {

	tx, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}

	err, unsList := (&dao.UBType{}).SelectUns(c, tx)
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	middleware.ResponseSuccess(c, unsList)
}

//定义一个内容为数字的不定长度数组
var arr [5]int

//获取产品
func (o *OrderController) ProductInfo(c *gin.Context) {

	tx, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	parms := &dto.Sort{}
	if err := parms.BindingValidParams(c); err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}

	err, product := (&dao.Product{}).FindProduct2(c, tx, parms.Id)
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	middleware.ResponseSuccess(c, product)
}

//创建订单 生成预付款
func (o *OrderController) Create(c *gin.Context) {

	tx, err := lib.GetGormPool("default")
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	parms := &dto.Order{}
	if err := parms.BindingValidParams(c); err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}

	err, product := (&dao.Order{}).CreateOrder(c, tx, parms)
	if err != nil {
		middleware.ResponseError(c, 100, err)
		return
	}
	middleware.ResponseSuccess(c, product)
}

// NotifyUrl 支付回调
func (o *OrderController) NotifyUrl(c *gin.Context) {

	var (
		mchID       string = "1617872033"                       // 商户号
		mchAPIv3Key string = "3064fe4604d1d08b5490b6ff093ce022" // 商户APIv3密钥
	)
	certVisitor := downloader.MgrInstance().GetCertificateVisitor(mchID)
	handler := notify.NewNotifyHandler(mchAPIv3Key, verifiers.NewSHA256WithRSAVerifier(certVisitor))
	transaction := new(payments.Transaction)
	_, err := handler.ParseNotifyRequest(context.Background(), c.Request, transaction)
	if err != nil {
		log.Println(err)
		//todo 写日志文件或者数据库记录错误日志 需要把所有的支付 c.Request存储起来
		return
	}
	//todo update order 协成 （协成处理 增大并发量）
	go func() {
		log.Println(*transaction)
		//*transaction.SuccessTime
		log.Println(*transaction.TradeState)
		log.Println(*transaction.Payer.Openid)
		log.Println(*transaction.OutTradeNo)
		//todo 会员短信通知 订单状态修改 商家发货通知 邮件
		if *transaction.TradeState == "SUCCESS" {
			tx, err := lib.GetGormPool("default")
			if err != nil {
				middleware.ResponseError(c, 100, err)
				return
			}
			log.Println(*transaction.OutTradeNo + "订单执行了回调")
			err, upRes := (&dao.Order{}).OrpSave(c, tx, *transaction.OutTradeNo, 0)
			if upRes == "0" {
				c.JSON(200, "SUCCESS")
			}
		}
	}()

}
